package auctionhaus
//Authors: Paul Kleczka, Adam Backstrom



import grails.test.mixin.*
import org.junit.*

/**
 * See the API for {@link grails.test.mixin.domain.DomainClassUnitTestMixin} for usage instructions
 */
@TestFor(Bid)
@Mock(Listing)
class BidTests {

//Note:    requirement B-4: A Listing has a list of Bids for that Listing -- is tested in auctionhaus.ListingTests

    //Tests for requirements:
    //B-1: Bids have the following required fields: amount and date/time of bid
    //B-2: Bids are required to be for a Listing
    //B-3: Bids are required to have a bidder
    void testValidBid(){
        float amount
        Date bidDateTime = new Date()
        Float startingBidPrice = 10
        Customer bidder = new Customer(email: "adambackstrom@gmail.com",password: "78910")
        Customer seller = new Customer(email: "kleczka@gmail.com",password: "123456")

        Listing listing = new Listing(name: "sale listing",
                endDateTime: bidDateTime + 2,
                startingBidPrice: startingBidPrice,
                seller: seller)
        listing.save(flush: true)

        listing.save(flush: true)
        Bid bid = new Bid(amount: 10,
                    bidDateTime: bidDateTime,
                    listing:  listing,
                    bidder:  bidder )
        assert bid.validate()

        bid.save(flush: true)
        Bid foundBid = Bid.findByBidDateTime(bidDateTime)
        
        assert foundBid
        assert foundBid.amount
        assert foundBid.bidDateTime
        assert foundBid.listing
        assert foundBid.bidder
    }

    //Tests for B-1, B-2, B-3
    void testConstraints(){
        float amount
        Date bidDateTime = new Date()
        Float startingBidPrice = 32.50
        Customer bidder = new Customer(email: "adambackstrom@gmail.com",password: "78910")
        Customer seller = new Customer(email: "kleczka@gmail.com",password: "123456")

        Listing listing = new Listing(name: "sale listing",
                endDateTime: bidDateTime + 2,
                startingBidPrice: startingBidPrice,
                seller: seller)
        listing.save(flush: true)

        Bid existingBid = new Bid(amount: 10,
                bidDateTime: bidDateTime,
                listing:  listing,
                bidder:  bidder )
        
        mockForConstraintsTests(Bid, [existingBid])

        Bid bid = new Bid()

        assert !bid.validate()
        assert "nullable" == bid.errors["bidDateTime"]
        assert "nullable" == bid.errors["listing"]
        assert "nullable" == bid.errors["bidder"]
        assert "min" == bid.errors["amount"]
    }

    //Tests for B-1, B-2, B-3
    void testNullables(){

        Bid bid = new Bid()
        bid.save(flush: true)

        assertEquals 'nullable',bid.errors['listing'].code
        assertEquals 'nullable',bid.errors['bidDateTime'].code
        assertEquals 'nullable',bid.errors['bidder'].code
        assertEquals 'min.notmet',bid.errors['amount'].code
    }

    //Test that you can't bid amount $.00
    void testAmountGreaterThanZero(){
        float amount
        Date bidDateTime = new Date()
        Float startingBidPrice = 10
        Customer bidder = new Customer(email: "adambackstrom@gmail.com",password: "78910")
        Customer seller = new Customer(email: "kleczka@gmail.com",password: "123456")

        Listing listing = new Listing(name: "sale listing",
                endDateTime: bidDateTime + 2,
                startingBidPrice: startingBidPrice,
                seller: seller)
        listing.save(flush: true)

        Bid bid = new Bid(amount: 0.00,
                bidDateTime: bidDateTime,
                listing:  listing,
                bidder:  bidder )
        assert !bid.validate()
        bid.save(flush: true)

        assertEquals 'min.notmet',bid.errors['amount'].code
    }


    void testNamedQuery(){
        float amount
        Date bidDateTime = new Date()
        Float startingBidPrice = 10
        Customer bidder = new Customer(email: "adambackstrom@gmail.com",password: "78910")
        Customer seller = new Customer(email: "kleczka@gmail.com",password: "123456")

        Listing listing = new Listing(name: "sale listing",
                endDateTime: bidDateTime + 2,
                startingBidPrice: startingBidPrice,
                seller: seller)
        listing.save(flush: true)

        listing.save(flush: true)
        Bid bid = new Bid(amount: 10,
                bidDateTime: bidDateTime,
                listing:  listing,
                bidder:  bidder )
        assert bid.validate()

        bid.save(flush: true)
        Bid foundBid = Bid.findByBidDateTime(bidDateTime)
        def listOfBids = Bid.bidsByListing(listing).list()
        assertEquals( 1, listOfBids.size())
        print listOfBids
    }
        
}
